/**
 * This class represents Delicious user.
 * 
 * @param login -
 *            user login
 * @param auth -
 *            encoded user auth token.
 * @returns {User} - user
 */
function User(login, auth) {
    this.login = login;
    this.auth = auth;
}

User.method('getLogin', function() {
    return this.login;
});

User.method('getAuth', function() {
    return this.auth;
});

var StorageContext = {

    USER_STORAGE_KEY : "USER_STORAGE_KEY",

    TAGS_STORAGE_KEY : "TAGS_STORAGE_KEY",

    BOOKMARKS_STORAGE_KEY : "BOOKMARKS_STORAGE_KEY"

};

/**
 * User Storage.
 *  { 'login' : 'value', 'auth' : 'value' }
 * 
 */
var UserStorage = {

    getUser : function() {
        var rawUser = JSON.parse(localStorage.getItem(StorageContext.USER_STORAGE_KEY));
        if (rawUser != null) {
            return new User(rawUser.login, rawUser.auth);
        } else {
            return null;
        }
    },

    storeUser : function(user) {
        localStorage.removeItem(StorageContext.USER_STORAGE_KEY);
        localStorage.setItem(StorageContext.USER_STORAGE_KEY, JSON
                .stringify(user));
    },

    cleanUser : function() {
        localStorage.removeItem(StorageContext.USER_STORAGE_KEY);
    }

};

/**
 * Bookmarks storage. { 'tag' : 'tag name value', 'description' : 'tag
 * description', 'bookmarks' : [ { 'name' : 'value', 'description' :
 * 'description', 'date' : 'date', 'url' : 'url' } ] }
 * 
 * 
 */
var BookmarksStorage = {

    getTags : function() {
        // TODO Mock
        return [ {
            tag : 'test tag',
            description : 'Tag description',
            bookmarks : [ {
                name : 'bookmark1',
                description : 'description1',
                url : 'www.tut.by'
            } ]
        } ];
    },

    getTagByName : function(tagName) {
        // TODO
    },

    storeTags : function(tags) {
        // TODO
    }

};

/**
 * Validator.
 */
var Validator = {

    /**
     * Validates login of user.
     * 
     * @param login -
     *            login entered by user.
     * @returns true if login in not null or empty else false.
     */
    validateLogin : function(login) {
        return this.validateNotEmpty(login);
    },

    /**
     * Validates password of user.
     * 
     * @param password
     * @returns
     */
    validatePassword : function(password) {
        return this.validateNotEmpty(password);
    },

    validateNotEmpty : function(field) {
        return field != null && field != undefined && field.length > 0;
    }

};

/**
 * Extension controller.
 */
var ExtensionController = {

    /**
     * Initialization of extension.
     */
    initExtension : function() {
        UIManager.initHandlers();
        UIManager.notifyOfChanges();
        $("#dialog").hide();
    },

    /**
     * Checks wheather user is already logged in.
     * 
     * @returns {Boolean}
     */
    isUserLogged : function() {
        var user = UserStorage.getUser();
        return !(user == null || user == undefined);
    },

    /**
     * Performs login.
     */
    logIn : function() {
        var login = $("#login").val();
        var password = $("#password").val();

        if (!Validator.validateLogin(login)
                || !Validator.validatePassword(password)) {
            UIManager.showLoginErrorForm();
            return;
        }

        var auth = Base64.encode(login + ":" + password);
        var user = new User(login, auth);

        UserStorage.storeUser(user);
        UIManager.notifyOfChanges();
    },

    /**
     * Performs log out.
     */
    logOut : function() {
        UserStorage.cleanUser();
        UIManager.notifyOfChanges();
    },

    /**
     * Perfoms sync operation with Delicious.
     */
    sync : function() {
        // TODO
    },

    /**
     * Shows debug info.
     */
    debug : function() {
        var tag = '2read';
        var callback = function(result){
            $(result).find('tag').each(
                    function() {
                        var count = $(this).attr('count');
                        var tag = $(this).attr('tag');
                        $("#content").append(
                                "<h3><a id='tag_" + tag + "' href=\"#\">" + tag + " ("
                                        + count + ") </a></h3><div id='tag_" + tag
                                        + "_content'>&nbsp;</div>");
                        $("#tag_" + tag).click(function() {
                            var user = UserStorage.getUser();
                            RequestManager.fetchPostsByTag(user.auth, tag);
                        });
                    });
            $("#content").accordion({
                collapsible : true
            });
        };
        Delicious.fetchTags(UserStorage.getUser().auth, callback);
    }

};

/**
 * UI Manager.
 */
var UIManager = {

    /**
     * Notifies UI controls of changes made by user.
     */
    notifyOfChanges : function() {
        if (ExtensionController.isUserLogged()) {
            UIManager.showMainForm(UserStorage.getUser());
        } else {
            UIManager.showLoginForm();
        }
    },

    showLoginForm : function() {
        $("#login_form").show();
        $("#user_info").html("");
        $("#main_form").hide();
    },

    /**
     * Shows main form only if use is logged.
     * 
     * @param user -
     *            logged user info.
     */
    showMainForm : function(user) {
        $("#login_form").hide();
        $("#user_info").html(user.login);
        $("#main_form").show();
    },

    initHandlers : function() {
        $("#login_button").click(function() {
            ExtensionController.logIn()();
        });
        $("#logout_button").click(function() {
            ExtensionController.logOut()();
        });
        $("#debug_button").click(function() {
            ExtensionController.debug();
        });
    },

    showLoginErrorForm : function() {
        $("#dialog").dialog({
            modal : true,
			show: {effect: "fadeIn", duration: 1000},
			hide : {effect : "fadeOut", duration: 500},
            buttons : {
                Ok : function() {
                    $(this).dialog("close");
                }
            }
        });        
    }
};
